package com.example.qianjun.gobang01.robot_player;

import android.graphics.Point;
import android.util.Log;

import com.example.qianjun.gobang01.bean.Constant;
import com.example.qianjun.gobang01.bean.EvaluePoint;
import com.example.qianjun.gobang01.bean.GobangCheckboard;
import com.example.qianjun.gobang01.util.ReferenceInit;

import java.util.Arrays;

/**
 * Created by qianjun on 2016/5/3.
 */
public class Evaluation {




    //最终取落子点的队列
    public static EvaluePoint[] getPoint = new EvaluePoint[5];
    //最终取落子点的队列初始化标志
    public static boolean getPointinitFlag = true;

    //获取棋盘数据
    public static GobangCheckboard gobangCheckboard = ReferenceInit.getGobangCheckboard();
    public static int[][] tableCheckboard = gobangCheckboard.getTable();
    public static int table_x = gobangCheckboard.getTable_x();
    public static int table_y = gobangCheckboard.getTable_y();


    public static void init() {

        //Constant.chessStyleInit();

        //获取棋盘数据
        GobangCheckboard gobangCheckboard = ReferenceInit.getGobangCheckboard();
        tableCheckboard = gobangCheckboard.getTable();
        table_x = gobangCheckboard.getTable_x();
        table_y = gobangCheckboard.getTable_y();


        EvaluePointScore.evaluepointScoreInit();
    }


    //新手级的落子点计算
    public static Point getLevelFirstBestPoint(int pieceType) {
        int[][] table = tableCheckboard;

        //要返回的最佳点位
        Point point = new Point();

        //记录当前点位的最高得分
        int maxScore = 0;

        int pieceScore = 0;
        //黑子在此点位的得分
        int blackPieceScore = 0;
        //白字在此点位的得分
        int whitepieceScore = 0;

        //循环遍历所有的空白点位，并且评分
        for (int i = 0; i < table_x; i++) {
            for (int j = 0; j < table_y; j++) {
                if (table[i][j] == Constant.NO_PIECES) {


                    //模拟黑子在此处落子的得分
                    blackPieceScore = getPieceScore(i, j, Constant.BLACK_PIECE, table);


                    //模拟白子在此处落子的得分
                    whitepieceScore = getPieceScore(i, j, Constant.WHITE_PIECE, table);
                    //总分判断，取最高分
                    if ((whitepieceScore + blackPieceScore) > maxScore) {
                        maxScore = whitepieceScore + blackPieceScore;
                        point.set(i, j);
                    }

                }

            }
        }

        Log.i("mike"," 新手级得分："+maxScore);

        return point;
    }

    //入门级的落子点计算
    public static Point getLevelSecondBestPoint(int pieceType) {

        //预测一步
        //返回最佳落子点
        EvaluePoint point = searchScoreDepthForBestPoint(pieceType, tableCheckboard, 1);

        Log.i("mike", "入门级得分：" + point.getScore());
        return point.getPoint();
    }

    //困难级的落子点计算
    public static Point getLevelThirdBestPoint(int pieceType) {


        //预测3步
        //返回最佳落子点
        EvaluePoint point = searchScoreDepthForBestPoint(pieceType, tableCheckboard, 2);

        Log.i("mike", "困难级得分：" + point.getScore());
        return point.getPoint();


    }

    //专家级的落子点计算
    public static Point getLevelFourthBestPoint(int pieceType) {


        //预测5步
        //返回最佳落子点
        EvaluePoint point = searchScoreDepthForBestPoint(pieceType, tableCheckboard, 3);

        Log.i("mike", "专家级得分：" + point.getScore());
        return point.getPoint();
    }

    //-----------------------------------------------------------------------------------------------------
    //评分深度，为1表示预测下一步对手棋，为2表示继续预测自己的下一步棋，为3表示继续预测对手棋~~~~~~
    public static EvaluePoint searchScoreDepthForBestPoint(int pieceType, int[][] table, int searchDepth) {




        //首先找出当前局势下的5个评分最高的点
        /***********************************************************************************/

        //计数标志，是否将前五个加入估值队列
        int count = 0;
        //黑子在此点位的得分
        int blackPieceScore = 0;
        //白字在此点位的得分
        int whitepieceScore = 0;

        int pieceScore = 0;

        EvaluePoint maxScorePoint = new EvaluePoint(new Point(0, 0), Integer.MIN_VALUE);

        //复用棋子
        EvaluePoint evaluePoint = new EvaluePoint(new Point(0, 0), Integer.MIN_VALUE);


        //对手得分
        int score = 0;
        //对手棋子
        EvaluePoint opponentPoint = new EvaluePoint(new Point(0, 0), Integer.MIN_VALUE);


        boolean scoreOrderFlag = true;
        //循环遍历所有的空白点位，并且评分,找到5个分数最高的，进行下一步预测
        for (int i = 0; i < table_x; i++) {
            for (int j = 0; j < table_y; j++) {
                if (table[i][j] == Constant.NO_PIECES) {

//                    //模拟黑子在此处落子的得分
                    blackPieceScore = getPieceScore(i, j, Constant.BLACK_PIECE, table);
                    Log.i("tttttt","heiqi："+blackPieceScore);
//                    //模拟白子在此处落子的得分
                    whitepieceScore = getPieceScore(i, j, Constant.WHITE_PIECE, table);

                    Log.i("tttttt","白棋的分："+whitepieceScore);

                    if (blackPieceScore >= 600000 || whitepieceScore >= 600000) {
                        pieceScore = blackPieceScore > whitepieceScore ? blackPieceScore : whitepieceScore;
                    } else {
                        pieceScore = blackPieceScore + whitepieceScore;
                    }

                    //初始化复用棋子
                    evaluePoint.setPointPosition(i,j);


                    //将棋子加入虚拟棋盘
                    addVirtualAndTable(table, evaluePoint, pieceType);

                    //对对手棋子进行评分
                    if (pieceType == Constant.BLACK_PIECE) {
                        opponentPoint = getMaxScore(Constant.WHITE_PIECE, table);

                    } else if (pieceType == Constant.WHITE_PIECE) {
                        opponentPoint = getMaxScore(Constant.BLACK_PIECE, table);

                    }
                    score = opponentPoint.getScore();


                    if(pieceScore >= 2900000 ||(pieceScore>=600000 && score< 2900000)){

                    }else{
                        pieceScore = pieceScore - score;
                    }

                    evaluePoint.setScore(pieceScore);




//                    if ((--searchDepth) > 0) {
//
//                        Log.i("tom","搜索深度："+searchDepth);
//                        //将对手棋子加入棋盘
//                        //将棋子加入虚拟棋盘
//                        addVirtualAndTable(table, opponentPoint, pieceType==Constant.BLACK_PIECE?Constant.WHITE_PIECE:Constant.BLACK_PIECE);
//                        pieceScore += searchScoreDepthForBestPoint(pieceType,table,searchDepth).getScore();
//                    }

                    removePointFromTable(table,evaluePoint);
                    removePointFromTable(table,opponentPoint);

                    if (pieceScore > maxScorePoint.getScore()) {
                        maxScorePoint.setPointPosition(i, j);
                        maxScorePoint.setScore(pieceScore);
                    }


                }

            }
        }




        return maxScorePoint;
    }


    //棋子与评分加入将要估值的队列
    public static void addEvaluePointsAndScore(EvaluePoint[] evaluePoints, EvaluePoint evaluePoint) {

        for (int i = 3; i >= 0; i--) {
            evaluePoints[i + 1] = evaluePoints[i];
        }
        evaluePoints[0] = evaluePoint;
    }


    //评分初始化冒泡排序
    public static void scoreOrderinit(EvaluePoint[] evaluePoints) {

        EvaluePoint evaluePoint;
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4 - i; j++) {
                if (evaluePoints[j].getScore() > evaluePoints[j + 1].getScore()) {
                    evaluePoint = evaluePoints[j];
                    evaluePoints[j] = evaluePoints[j + 1];
                    evaluePoints[j + 1] = evaluePoint;
                }
            }
        }


    }

    //评分初始化以后，新评分加入，比较大小并排序
    public static void addEvaluePoint(EvaluePoint[] evaluePoints, EvaluePoint evaluePoint) {
        //当传入的落子的得分大于估值队列中最小的得分点，替换掉最小点，进行一次排序
        if (evaluePoint.getScore() > evaluePoints[0].getScore()) {
            evaluePoints[0] = evaluePoint;
            EvaluePoint e;
            for (int i = 0; i < 4; i++) {
                if (evaluePoints[i].getScore() > evaluePoints[i + 1].getScore()) {
                    e = evaluePoints[i];
                    evaluePoints[i] = evaluePoints[i + 1];
                    evaluePoints[i + 1] = e;
                }
            }
        }
    }

    //棋子加入虚拟落子棋盘
    public static void addVirtualAndTable(int[][] table, EvaluePoint point, int pieceType) {

        table[point.getPoint().x][point.getPoint().y] = pieceType;
    }

    //棋子从虚拟落子棋盘中移除
    public static void removePointFromTable(int[][] table, EvaluePoint point) {
        table[point.getPoint().x][point.getPoint().y] = Constant.NO_PIECES;
    }


    //获取5个点中得分最高的点
    public static EvaluePoint getMaxScoreFromFivePoints(EvaluePoint[] evaluePoints) {
        EvaluePoint point = evaluePoints[0];
        //然后从这5个点中，取出得分最高的点
        int maxScore = evaluePoints[0].getScore();
        for (int i = 1; i < 5; i++) {
            if (maxScore < evaluePoints[i].getScore()) {
                maxScore = evaluePoints[i].getScore();
                point = evaluePoints[i];
            }
        }

        return point;
    }


    //获取棋盘中黑子或者白子在棋盘中的最高得分
    public static EvaluePoint getMaxScore(int piecetype, int[][] tableForMaxScore) {
        EvaluePoint evaluePoint = new EvaluePoint();
        Point point = new Point();
        int maxScore = 0;

        for (int i = 0; i < table_x; i++) {
            for (int j = 0; j < table_y; j++) {
                if (tableForMaxScore[i][j] == Constant.NO_PIECES) {
                    int score = 0;
                    if (piecetype == Constant.BLACK_PIECE) {
                        score = getPieceScore(i, j, Constant.BLACK_PIECE, tableForMaxScore);

                    } else if (piecetype == Constant.WHITE_PIECE) {
                        score = getPieceScore(i, j, Constant.WHITE_PIECE, tableForMaxScore);
                    }


                    if (score > maxScore) {
                        maxScore = score;
                        point.set(i, j);
                        evaluePoint.setPoint(point);
                        evaluePoint.setScore(maxScore);
                    }
                }
            }
        }

        return evaluePoint;
    }


    //获取棋子在该点的得分
    public static int getPieceScore(int i, int j, int piecetype, int[][] tableForScore) {
        return EvaluePointScore.getHorizontal(i, j, piecetype, tableForScore) + EvaluePointScore.getVertical(i, j, piecetype, tableForScore)
                + EvaluePointScore.getLeft(i, j, piecetype, tableForScore) + EvaluePointScore.getRight(i, j, piecetype, tableForScore);
    }


//    //获取黑子在此处落子的得分
//    public static int getBlackPieceScore(int i, int j, int piecetype, int[][] table) {
//        return EvaluePointScore.getHorizontal(i, j, piecetype, table) + EvaluePointScore.getVertical(i, j, piecetype, table)
//                + EvaluePointScore.getLeft(i, j, piecetype, table) + EvaluePointScore.getRight(i, j, piecetype, table);
//    }
//
//    //获取白子在此处落子的得分
//    public static int getWhitePieceScore(int i, int j, int piecetype, int[][] table) {
//        return EvaluePointScore.getHorizontal(i, j, Constant.WHITE_PIECE, table) + EvaluePointScore.getVertical(i, j, Constant.WHITE_PIECE, table)
//                + EvaluePointScore.getLeft(i, j, Constant.WHITE_PIECE, table) + EvaluePointScore.getRight(i, j, Constant.WHITE_PIECE, table);
//    }


//    //计算该点棋子横向的棋型得分
//    public static int getHorizontal(int i, int j, int piecesTYPE, int[][] table) {
//
//        //开始端是否堵住
//        boolean isHeadBlock = false;
//        //尾端是否堵住
//        boolean isEndBlock = false;
//        //连续出现的棋子
//        int count = 1;
//
//        //如果在最左边，或者左方有其他颜色的棋子
//        if (i == 0 || (table[i - 1][j] != piecesTYPE && table[i - 1][j] != Constant.NO_PIECES)) {
//            isHeadBlock = true;
//        }
//        //如果是在最右面，或者右方有其他颜色的棋子
//        if (i == (table_x - 1) || (table[i + 1][j] != piecesTYPE && table[i + 1][j] != Constant.NO_PIECES)) {
//            isEndBlock = true;
//        }
//
//        for (int m = i - 1; m >= 0; m--) {
//            if (table[m][j] != piecesTYPE) {
//                break;
//            }
//            count++;
//        }
//
//        for (int m = i + 1; m < table_x; m++) {
//            if (table[m][j] != piecesTYPE) {
//                break;
//            }
//            count++;
//        }
//
//
//        return getPointScoreForSmartFirst(count, isHeadBlock, isEndBlock);
//    }
//
//    //计算该点棋子纵向的棋型得分
//    public static int getVertical(int i, int j, int piecesTYPE, int[][] table) {
//        //开始端是否堵住
//        boolean isHeadBlock = false;
//        //尾端是否堵住
//        boolean isEndBlock = false;
//        //连续出现的棋子
//        int count = 1;
//
//        //如果在最上边，或者上方是其他颜色的棋子
//        if (j == 0 || (table[i][j - 1] != piecesTYPE && table[i][j - 1] != Constant.NO_PIECES)) {
//            isHeadBlock = true;
//        }
//        //如果是在最下面，或者下方有其他颜色的棋子
//        if (j == (table_y - 1) || (table[i][j + 1] != piecesTYPE && table[i][j + 1] != Constant.NO_PIECES)) {
//            isEndBlock = true;
//        }
//
//        for (int m = j - 1; m >= 0; m--) {
//            if (table[i][m] != piecesTYPE) {
//                break;
//            }
//            count++;
//        }
//
//        for (int m = j + 1; m < table_y; m++) {
//            if (table[i][m] != piecesTYPE) {
//                break;
//            }
//            count++;
//        }
//
//
//        return getPointScoreForSmartFirst(count, isHeadBlock, isEndBlock);
//    }
//
//    //计算该点棋型左上右下得分
//    public static int getLeft(int i, int j, int piecesTYPE, int[][] table) {
//        //开始端是否堵住
//        boolean isHeadBlock = false;
//        //尾端是否堵住
//        boolean isEndBlock = false;
//        //连续出现的棋子
//        int count = 1;
//
//        //如果在左上方，或者左上方是其他颜色的棋子
//        if ((i == 0 || j == 0) || (table[i - 1][j - 1] != piecesTYPE && table[i - 1][j - 1] != Constant.NO_PIECES)) {
//            isHeadBlock = true;
//        }
//        //如果是在右下方，或者右下方有其他颜色的棋子
//        if ((i == (table_x - 1) || j == (table_y - 1)) || (table[i + 1][j + 1] != piecesTYPE && table[i + 1][j + 1] != Constant.NO_PIECES)) {
//            isEndBlock = true;
//        }
//
//        for (int m = i - 1, n = j - 1; m >= 0 && n >= 0; m--, n--) {
//            if (table[m][n] != piecesTYPE) {
//                break;
//            }
//            count++;
//        }
//
//        for (int m = i + 1, n = j + 1; m < table_x && n < table_y; m++, n++) {
//            if (table[m][n] != piecesTYPE) {
//                break;
//            }
//            count++;
//        }
//
//
//        return getPointScoreForSmartFirst(count, isHeadBlock, isEndBlock);
//    }
//
//    //计算该点棋型左下右上得分
//    public static int getRight(int i, int j, int piecesTYPE, int[][] table) {
//        //开始端是否堵住
//        boolean isHeadBlock = false;
//        //尾端是否堵住
//        boolean isEndBlock = false;
//        //连续出现的棋子
//        int count = 1;
//
//        //如果在左下方，或者左下方是其他颜色的棋子
//        if ((i == 0 || j == (table_y - 1)) || (table[i - 1][j + 1] != piecesTYPE && table[i - 1][j + 1] != Constant.NO_PIECES)) {
//            isHeadBlock = true;
//        }
//        //如果是在右上方，或者右上方有其他颜色的棋子
//        if (i == (table_x - 1) || j == 0 || (table[i + 1][j - 1] != piecesTYPE && table[i + 1][j - 1] != Constant.NO_PIECES)) {
//            isEndBlock = true;
//        }
//
//        for (int m = i - 1, n = j + 1; m >= 0 && n < table_y; m--, n++) {
//            if (table[m][n] != piecesTYPE) {
//                break;
//            }
//            count++;
//        }
//
//        for (int m = i + 1, n = j - 1; m < table_x && n >= 0; m++, n--) {
//            if (table[m][n] != piecesTYPE) {
//                break;
//            }
//            count++;
//        }
//
//        return getPointScoreForSmartFirst(count, isHeadBlock, isEndBlock);
//    }
//
//    //根据传入的棋行计算分值
//    public static int getPointScoreForSmartFirst(int count, boolean isHeadBlock, boolean isEndBlock) {
//        //返回五子连珠的分值
//        if (count >= 5) {
//            return Constant.FIRTS_LEVEL_FIVE_PIECE;
//        }
//        //返回两头被堵的分值
//        if (isHeadBlock && isEndBlock) {
//            return Constant.FIRTS_LEVEL_DEAD;
//        }
//
//        //返回两头被堵的情况的分值
//        if (isHeadBlock && isEndBlock) {
//            switch (count) {
//                case 4:
//                    return Constant.FIRTS_LEVEL_FOUR_PIECE_DEAD;
//                case 3:
//                    return Constant.FIRTS_LEVEL_THREE_PIECE_DEAD;
//                case 2:
//                    return Constant.FIRTS_LEVEL_TWO_PIECE_DEAD;
//                case 1:
//                    return Constant.FIRTS_LEVEL_ONE_PIECE_DEAD;
//            }
//        }
//
//        //返回一头被堵情况的分值
//        if (isEndBlock || isHeadBlock) {
//            switch (count) {
//                case 4:
//                    return Constant.FIRTS_LEVEL_FOUR_PIECE;
//                case 3:
//                    return Constant.FIRTS_LEVEL_THREE_PIECE;
//                case 2:
//                    return Constant.FIRTS_LEVEL_TWO_PIECE;
//                case 1:
//                    return Constant.FIRTS_LEVEL_ONE_PIECE;
//            }
//        }
//        //返回两端都没有被堵得分值
//        switch (count) {
//            case 4:
//                return Constant.FIRTS_LEVEL_LIVE_FOUR_PIECE;
//            case 3:
//                return Constant.FIRTS_LEVEL_LIVE_THREE_PIECE;
//            case 2:
//                return Constant.FIRTS_LEVEL_LIVE_TWO_PIECE;
//            case 1:
//                return Constant.FIRTS_LEVEL_LIVE_ONE_PIECE;
//            default:
//                return 0;
//        }
//
//    }




}
